package com.qisu.command;


import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.qisu.cacheMap.ChargeQuantity;
import com.qisu.cacheMap.OrderIdCache;
import com.qisu.cacheMap.TimeAndPriceCache;
import com.qisu.converters.Converters;
import com.qisu.model.packet.SettlementPacket;
import com.qisu.model.vo.PayMent;
import com.qisu.service.OrderService;
import com.qisu.service.SettlementService;

import io.netty.channel.ChannelHandlerContext;

/**
 * 结算包
 * @author li
 *
 */
@Component
public class CMD202 extends AbstractSinexcelCmd {
	@Autowired private OrderService orderService;
	@Autowired private SettlementService settlementService;

	@Autowired OrderIdCache orderIdCache;
	@Autowired TimeAndPriceCache timeAndPriceCache;
	@Autowired private ChargeQuantity chargeQuantity;
	
	@PostConstruct
	@Override
	protected void init() {
		super.init();

		fieldsList.addField(new CommandFieldDef<Integer>(2))
				.addField(new CommandFieldDef<Integer>(2))
				.addField(new CommandFieldDef<String>(32, Converters.strConverter, "充电桩ID"))
				.addField(new CommandFieldDef<Byte>(1, Converters.byteConverter, "充电枪位置类型"))
				.addField(new CommandFieldDef<Byte>(1, Converters.byteConverter, "充电枪口"))
				.addField(new CommandFieldDef<String>(32, Converters.strConverter, "充电卡号"))
				.addField(new CommandFieldDef<String>(8, Converters.hexConverter, "充电开始时间"))
				.addField(new CommandFieldDef<String>(8, Converters.hexConverter, "充电结束时间"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "充电时长"))
				.addField(new CommandFieldDef<Byte>(1, Converters.byteConverter, "开始SOC"))
				.addField(new CommandFieldDef<Byte>(1, Converters.byteConverter, "结束SOC"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "充电结束原因"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "本次充电电量"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "充电前电表读数"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "充电后电表读数"))
				.addField(new CommandFieldDef<Integer>(4, Converters.intConverter, "本次充电金额"))
				.addField(new CommandFieldDef<Integer>(4))
				.addField(new CommandFieldDef<Integer>(4/*, Converters.intConverter, "当前充电记录索引"*/))
				.addField(new CommandFieldDef<Integer>(4/*, Converters.seIntConverter, "总充电记录条目"*/))
				.addField(new CommandFieldDef<Byte>(1))
				.addField(new CommandFieldDef<Byte>(1, Converters.byteConverter, "充电策略"))
				.addField(new CommandFieldDef<Integer>(4, Converters.seIntConverter, "策略单位"))
				.addField(new CommandFieldDef<String>(17, Converters.strConverter, "车辆VIN"))
				.addField(new CommandFieldDef<String>(8, Converters.strConverter, "车牌号"));
	}

	@Override
	public void processCmd(ChannelHandlerContext ctx, byte[] req) throws Exception  {
		
		String pileSerial = fieldsList.getValue("充电桩ID");
		int gunNo = ((Byte)fieldsList.getValue("充电枪口")).intValue();
//		int gunNo = 1;  //目前固定为1与db对应. 
		int chargeQualityInDegree =fieldsList.getValue("本次充电电量");
		
		responseClient(channelList.get(pileSerial));
		
		int increaseQuantity;
		int chargePrice;
		int servicePrice ;
		if (null == chargeQuantity.get(pileSerial+gunNo)) {
			chargeQualityInDegree=0;
			increaseQuantity = 0;
			chargePrice = 0;
			servicePrice = 0;
		}else {
			 increaseQuantity = chargeQualityInDegree - chargeQuantity.get(pileSerial+gunNo);
			if (increaseQuantity > 0) {
				orderService.getCurrentPrice(pileSerial, gunNo);
			}
			 chargePrice = timeAndPriceCache.get(pileSerial+gunNo).getChargePrice();
			 servicePrice = timeAndPriceCache.get(pileSerial+gunNo).getServicePrice();
		}
		int SOC = ((Byte)fieldsList.getValue("结束SOC")).intValue() - ((Byte)fieldsList.getValue("开始SOC")).intValue();
		String orderId = orderIdCache.get(pileSerial+gunNo);
		SettlementPacket packet = new SettlementPacket(orderId,chargeQualityInDegree,increaseQuantity,chargePrice,servicePrice,SOC);
		//获取订单状态
		PayMent payMent=orderService.getOrderInfo(orderId);
		if("02".equals(payMent.getOrderState())){
			orderService.updateOrder02to03(packet);
			log.info(" ===== 结束充电  ===== ");			
			settlementService.settlement(orderId);			
		}
		timeAndPriceCache.remove(pileSerial+gunNo);
		chargeQuantity.remove(pileSerial+gunNo);
		orderIdCache.remove(pileSerial+gunNo);
		
	}


	@Override
	protected void responseClient(ChannelHandlerContext ctx) {
		// cmd=201
		// @formatter:off
		byte[] p = new byte[] {
			(byte)0xAA, (byte)0xF5,							// signature
			(byte)0x0D, (byte)0x00, 						// length
			(byte)0x10, 									// version
			(byte)0x00,										// sequence
			(byte)0xc9, (byte)0x00, 						// command
			(byte)0x00, (byte)0x00, 						// preserved1
			(byte)0x00, (byte)0x00,							// preserved2
			fieldsList.getValue("充电枪口"),					// gun no
			(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
			(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
			(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
			(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
			(byte)0x00										// checksum
		};

		String stationId = fieldsList.getValue("充电桩ID");

		setCommand(p, 201);
		fillData(p, stationId.getBytes(), 13);
		send(ctx, p);
	}

}
